home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / namcos1.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  23KB  |  956 lines

  1. #include "driver.h"
  2. #include "vidhrdw/generic.h"
  3.  
  4. #define get_gfx_pointer(gfxelement,c,line) (gfxelement->gfxdata + (c*gfxelement->height+line) * gfxelement->line_modulo)
  5.  
  6. #define SPRITECOLORS 2048
  7. #define TILECOLORS 1536
  8. #define BACKGROUNDCOLOR (SPRITECOLORS+2*TILECOLORS)
  9.  
  10. /* support non use tilemap system draw routine */
  11. #define NAMCOS1_DIRECT_DRAW 1
  12.  
  13.  
  14. /*
  15.   video ram map
  16.   0000-1fff : scroll playfield (0) : 64*64*2
  17.   2000-3fff : scroll playfield (1) : 64*64*2
  18.   4000-5fff : scroll playfield (2) : 64*64*2
  19.   6000-6fff : scroll playfield (3) : 64*32*2
  20.   7000-700f : ?
  21.   7010-77ef : fixed playfield (4)  : 36*28*2
  22.   77f0-77ff : ?
  23.   7800-780f : ?
  24.   7810-7fef : fixed playfield (5)  : 36*28*2
  25.   7ff0-7fff : ?
  26. */
  27. static unsigned char *namcos1_videoram;
  28. /*
  29.   paletteram map (s1ram  0x0000-0x7fff)
  30.   0000-17ff : palette page0 : sprite
  31.   2000-37ff : palette page1 : playfield
  32.   4000-57ff : palette page2 : playfield (shadow)
  33.   6000-7fff : work ram ?
  34. */
  35. static unsigned char *namcos1_paletteram;
  36. /*
  37.   controlram map (s1ram 0x8000-0x9fff)
  38.   0000-07ff : work ram
  39.   0800-0fef : sprite ram    : 0x10 * 127
  40.   0ff0-0fff : display control register
  41.   1000-1fff : playfield control register
  42. */
  43. static unsigned char *namcos1_controlram;
  44.  
  45. #define FG_OFFSET 0x7000
  46.  
  47. #define MAX_PLAYFIELDS 6
  48. #define MAX_SPRITES    127
  49.  
  50. struct playfield {
  51.     void    *base;
  52.     int     scroll_x;
  53.     int     scroll_y;
  54. #if NAMCOS1_DIRECT_DRAW
  55.     int     width;
  56.     int     height;
  57. #endif
  58.     struct    tilemap *tilemap;
  59.     int     color;
  60. };
  61.  
  62. struct playfield playfields[MAX_PLAYFIELDS];
  63.  
  64. #if NAMCOS1_DIRECT_DRAW
  65. static int namcos1_tilemap_need = 0;
  66. static int namcos1_tilemap_used;
  67.  
  68. static unsigned char *char_state;
  69. #define CHAR_BLANK    0
  70. #define CHAR_FULL    1
  71. #endif
  72.  
  73. /* playfields maskdata for tilemap */
  74. static unsigned char **mask_ptr;
  75. static unsigned char *mask_data;
  76.  
  77. /* graphic object */
  78. static struct gfx_object_list *objectlist;
  79. static struct gfx_object *objects;
  80.  
  81. /* palette dirty information */
  82. static unsigned char sprite_palette_state[MAX_SPRITES+1];
  83. static unsigned char tilemap_palette_state[MAX_PLAYFIELDS];
  84.  
  85. /* per game scroll adjustment */
  86. static int scrolloffsX[4];
  87. static int scrolloffsY[4];
  88.  
  89. static int sprite_fixed_sx;
  90. static int sprite_fixed_sy;
  91. static int flipscreen;
  92.  
  93. void namcos1_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  94. {
  95.     int i;
  96.  
  97.     for (i = 0; i < Machine->drv->total_colors; i++) {
  98.         palette[i*3+0] = 0;
  99.         palette[i*3+1] = 0;
  100.         palette[i*3+2] = 0;
  101.     }
  102. }
  103.  
  104. static void namcos1_set_flipscreen(int flip)
  105. {
  106.     int i;
  107.  
  108.     int pos_x[] = {0x0b0,0x0b2,0x0b3,0x0b4};
  109.     int pos_y[] = {0x108,0x108,0x108,0x008};
  110.     int neg_x[] = {0x1d0,0x1d2,0x1d3,0x1d4};
  111.     int neg_y[] = {0x1e8,0x1e8,0x1e8,0x0e8};
  112.  
  113.     flipscreen = flip;
  114.     if(!flip)
  115.     {
  116.         for ( i = 0; i < 4; i++ ) {
  117.             scrolloffsX[i] = pos_x[i];
  118.             scrolloffsY[i] = pos_y[i];
  119.         }
  120.     }
  121.     else
  122.     {
  123.         for ( i = 0; i < 4; i++ ) {
  124.             scrolloffsX[i] = neg_x[i];
  125.             scrolloffsY[i] = neg_y[i];
  126.         }
  127.     }
  128. #if NAMCOS1_DIRECT_DRAW
  129.     if(namcos1_tilemap_used)
  130. #endif
  131.     tilemap_set_flip(ALL_TILEMAPS,flipscreen ? TILEMAP_FLIPX|TILEMAP_FLIPY : 0);
  132. }
  133.  
  134. static WRITE_HANDLER( namcos1_playfield_control_w )
  135. {
  136.     /* 0-15 : scrolling */
  137.     if ( offset < 16 )
  138.     {
  139.         int whichone = offset / 4;
  140.         int xy = offset & 2;
  141.         if ( xy == 0 ) { /* scroll x */
  142.             if ( offset & 1 )
  143.                 playfields[whichone].scroll_x = ( playfields[whichone].scroll_x & 0xff00 ) | data;
  144.             else
  145.                 playfields[whichone].scroll_x = ( playfields[whichone].scroll_x & 0xff ) | ( data << 8 );
  146.         } else { /* scroll y */
  147.             if ( offset & 1 )
  148.                 playfields[whichone].scroll_y = ( playfields[whichone].scroll_y & 0xff00 ) | data;
  149.             else
  150.                 playfields[whichone].scroll_y = ( playfields[whichone].scroll_y & 0xff ) | ( data << 8 );
  151.         }
  152.     }
  153.     /* 16-21 : priority */
  154.     else if ( offset < 22 )
  155.     {
  156.         /* bit 0-2 priority */
  157.         /* bit 3   disable    */
  158.         int whichone = offset - 16;
  159.         objects[whichone].priority = data & 7;
  160.         objects[whichone].visible = (data&0xf8) ? 0 : 1;
  161. #if NAMCOS1_DIRECT_DRAW
  162.         if(namcos1_tilemap_used)
  163. #endif
  164.         playfields[whichone].tilemap->enable = objects[whichone].visible;
  165.     }
  166.     /* 22,23 unused */
  167.     else if (offset < 24)
  168.     {
  169.     }
  170.     /* 24-29 palette */
  171.     else if ( offset < 30 )
  172.     {
  173.         int whichone = offset - 24;
  174.         if (playfields[whichone].color != (data & 7))
  175.         {
  176.             playfields[whichone].color = data & 7;
  177.             tilemap_palette_state[whichone] = 1;
  178.         }
  179.     }
  180. }
  181.  
  182. READ_HANDLER( namcos1_videoram_r )
  183. {
  184.     return namcos1_videoram[offset];
  185. }
  186.  
  187. WRITE_HANDLER( namcos1_videoram_w )
  188. {
  189.     if (namcos1_videoram[offset] != data)
  190.     {
  191.         namcos1_videoram[offset] = data;
  192. #if NAMCOS1_DIRECT_DRAW
  193.         if(namcos1_tilemap_used)
  194.         {
  195. #endif
  196.         if(offset < FG_OFFSET)
  197.         {    /* background 0-3 */
  198.             int layer = offset/0x2000;
  199.             int num = (offset &= 0x1fff)/2;
  200.             tilemap_mark_tile_dirty(playfields[layer].tilemap,num);
  201.         }
  202.         else
  203.         {    /* foreground 4-5 */
  204.             int layer = (offset&0x800) ? 5 : 4;
  205.             int num = ((offset&0x7ff)-0x10)/2;
  206.             if (num >= 0 && num < 0x3f0)
  207.                 tilemap_mark_tile_dirty(playfields[layer].tilemap,num);
  208.         }
  209. #if NAMCOS1_DIRECT_DRAW
  210.         }
  211. #endif
  212.     }
  213. }
  214.  
  215. READ_HANDLER( namcos1_paletteram_r )
  216. {
  217.     return namcos1_paletteram[offset];
  218. }
  219.  
  220. WRITE_HANDLER( namcos1_paletteram_w )
  221. {
  222.     if(namcos1_paletteram[offset] != data)
  223.     {
  224.         namcos1_paletteram[offset] = data;
  225.         if ((offset&0x1fff) < 0x1800)
  226.         {
  227.             if (offset < 0x2000)
  228.             {
  229.                 sprite_palette_state[(offset&0x7f0)/16] = 1;
  230.             }
  231.             else
  232.             {
  233.                 int i,color;
  234.  
  235.                 color = (offset&0x700)/256;
  236.                 for(i=0;i<MAX_PLAYFIELDS;i++)
  237.                 {
  238.                     if (playfields[i].color == color)
  239.                         tilemap_palette_state[i] = 1;
  240.                 }
  241.             }
  242.         }
  243.     }
  244. }
  245.  
  246. static void namcos1_palette_refresh(int start,int offset,int num)
  247. {
  248.     int color;
  249.  
  250.     offset = (offset/0x800)*0x2000 + (offset&0x7ff);
  251.  
  252.     for (color = start; color < start + num; color++)
  253.     {
  254.         int r,g,b;
  255.         r = namcos1_paletteram[offset];
  256.         g = namcos1_paletteram[offset + 0x0800];
  257.         b = namcos1_paletteram[offset + 0x1000];
  258.         palette_change_color(color,r,g,b);
  259.  
  260.         if (offset >= 0x2000)
  261.         {
  262.             r = namcos1_paletteram[offset + 0x2000];
  263.             g = namcos1_paletteram[offset + 0x2800];
  264.             b = namcos1_paletteram[offset + 0x3000];
  265.             palette_change_color(color+TILECOLORS,r,g,b);
  266.         }
  267.         offset++;
  268.     }
  269. }
  270.  
  271. static WRITE_HANDLER( namcos1_spriteram_w )
  272. {
  273.     static const int sprite_sizemap[4] = {16,8,32,4};
  274.     int num = offset / 0x10;
  275.     struct gfx_object *object = &objectlist->objects[num+MAX_PLAYFIELDS];
  276.     unsigned char *base = &namcos1_controlram[0x0800 + num*0x10];
  277.     int sx, sy;
  278.     int resize_x=0,resize_y=0;
  279.  
  280.     switch(offset&0x0f)
  281.     {
  282.     case 0x04:
  283.         /* bit.6-7 : x size (16/8/32/4) */
  284.         /* bit.5   : flipx */
  285.         /* bit.3-4 : x offset */
  286.         /* bit.0-2 : code.8-10 */
  287.         object->width = sprite_sizemap[(data>>6)&3];
  288.         object->flipx = ((data>>5)&1) ^ flipscreen;
  289.         object->left = (data&0x18) & (~(object->width-1));
  290.         object->code = (base[4]&7)*256 + base[5];
  291.         resize_x=1;
  292.         break;
  293.     case 0x05:
  294.         /* bit.0-7 : code.0-7 */
  295.         object->code = (base[4]&7)*256 + base[5];
  296.         break;
  297.     case 0x06:
  298.         /* bit.1-7 : color */
  299.         /* bit.0   : x draw position.8 */
  300.         object->color = data>>1;
  301.         object->transparency = object->color==0x7f ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN;
  302. #if 0
  303.         if(object->color==0x7f && !(Machine->gamedrv->flags & GAME_REQUIRES_16BIT))
  304.             usrintf_showmessage("This driver requires GAME_REQUIRES_16BIT flag");
  305. #endif
  306.     case 0x07:
  307.         /* bit.0-7 : x draw position.0-7 */
  308.         resize_x=1;
  309.         break;
  310.     case 0x08:
  311.         /* bit.5-7 : priority */
  312.         /* bit.3-4 : y offset */
  313.         /* bit.1-2 : y size (16/8/32/4) */
  314.         /* bit.0   : flipy */
  315.         object->priority = (data>>5)&7;
  316.         object->height = sprite_sizemap[(data>>1)&3];
  317.         object->flipy = (data&1) ^ flipscreen;
  318.         object->top = (data&0x18) & (~(object->height-1));
  319.     case 0x09:
  320.         /* bit.0-7 : y draw position */
  321.         resize_y=1;
  322.         break;
  323.     default:
  324.         return;
  325.     }
  326.     if(resize_x)
  327.     {
  328.         /* sx */
  329.         sx = (base[6]&1)*256 + base[7];
  330.         sx += sprite_fixed_sx;
  331.  
  332.         if(flipscreen) sx = 210 - sx - object->width;
  333.  
  334.         if( sx > 480  ) sx -= 512;
  335.         if( sx < -32  ) sx += 512;
  336.         if( sx < -224 ) sx += 512;
  337.         object->sx = sx;
  338.     }
  339.     if(resize_y)
  340.     {
  341.         /* sy */
  342.         sy = sprite_fixed_sy - base[9];
  343.  
  344.         if(flipscreen) sy = 222 - sy;
  345.         else sy = sy - object->height;
  346.  
  347.         if( sy > 224 ) sy -= 256;
  348.         if( sy < -32 ) sy += 256;
  349.         object->sy = sy;
  350.     }
  351.     object->dirty_flag = GFXOBJ_DIRTY_ALL;
  352. }
  353.  
  354. /* display control block write */
  355. /*
  356. 0-3  unknown
  357. 4-5  sprite offset x
  358. 6     flip screen
  359. 7     sprite offset y
  360. 8-15 unknown
  361. */
  362. static WRITE_HANDLER( namcos1_displaycontrol_w )
  363. {
  364.     unsigned char *disp_reg = &namcos1_controlram[0xff0];
  365.     int newflip;
  366.  
  367.     switch(offset)
  368.     {
  369.     case 0x02: /* ?? */
  370.         break;
  371.     case 0x04: /* sprite offset X */
  372.     case 0x05:
  373.         sprite_fixed_sx = disp_reg[4]*256+disp_reg[5] - 151;
  374.         if( sprite_fixed_sx > 480 ) sprite_fixed_sx -= 512;
  375.         if( sprite_fixed_sx < -32 ) sprite_fixed_sx += 512;
  376.         break;
  377.     case 0x06: /* flip screen */
  378.         newflip = (disp_reg[6]&1)^0x01;
  379.         if(flipscreen != newflip)
  380.         {
  381.             namcos1_set_flipscreen(newflip);
  382.         }
  383.         break;
  384.     case 0x07: /* sprite offset Y */
  385.         sprite_fixed_sy = 239 - disp_reg[7];
  386.         break;
  387.     case 0x0a: /* ?? */
  388.         /* 00 : blazer,dspirit,quester */
  389.         /* 40 : others */
  390.         break;
  391.     case 0x0e: /* ?? */
  392.         /* 00 : blazer,dangseed,dspirit,pacmania,quester */
  393.         /* 06 : others */
  394.     case 0x0f: /* ?? */
  395.         /* 00 : dangseed,dspirit,pacmania */
  396.         /* f1 : blazer */
  397.         /* f8 : galaga88,quester */
  398.         /* e7 : others */
  399.         break;
  400.     }
  401. #if 0
  402.     {
  403.         char buf[80];
  404.         sprintf(buf,"%02x:%02x:%02x:%02x:%02x%02x,%02x,%02x,%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
  405.         disp_reg[0],disp_reg[1],disp_reg[2],disp_reg[3],
  406.         disp_reg[4],disp_reg[5],disp_reg[6],disp_reg[7],
  407.         disp_reg[8],disp_reg[9],disp_reg[10],disp_reg[11],
  408.         disp_reg[12],disp_reg[13],disp_reg[14],disp_reg[15]);
  409.         usrintf_showmessage(buf);
  410.     }
  411. #endif
  412. }
  413.  
  414. WRITE_HANDLER( namcos1_videocontrol_w )
  415. {
  416.     namcos1_controlram[offset] = data;
  417.     /* 0000-07ff work ram */
  418.     if(offset <= 0x7ff)
  419.         return;
  420.     /* 0800-0fef sprite ram */
  421.     if(offset <= 0x0fef)
  422.     {
  423.         namcos1_spriteram_w(offset&0x7ff, data);
  424.         return;
  425.     }
  426.     /* 0ff0-0fff display control ram */
  427.     if(offset <= 0x0fff)
  428.     {
  429.         namcos1_displaycontrol_w(offset&0x0f, data);
  430.         return;
  431.     }
  432.     /* 1000-1fff control ram */
  433.     namcos1_playfield_control_w(offset&0xff, data);
  434. }
  435.  
  436. #if NAMCOS1_DIRECT_DRAW
  437. static void draw_background( struct osd_bitmap *bitmap, int layer )
  438. {
  439.     unsigned char *vid = playfields[layer].base;
  440.     int width    = playfields[layer].width;
  441.     int height    = playfields[layer].height;
  442.     int color    = objects[layer].color;
  443.     int scrollx = playfields[layer].scroll_x;
  444.     int scrolly = playfields[layer].scroll_y;
  445.     int sx,sy;
  446.     int offs_x,offs_y;
  447.     int ox,xx;
  448.     int max_x = Machine->drv->visible_area.max_x;
  449.     int max_y = Machine->drv->visible_area.max_y;
  450.     int code;
  451.  
  452.     scrollx -= scrolloffsX[layer];
  453.     scrolly -= scrolloffsY[layer];
  454.  
  455.     if ( flipscreen ) {
  456.         scrollx = -scrollx;
  457.         scrolly = -scrolly;
  458.     }
  459.  
  460.     if (scrollx < 0) scrollx = width - (-scrollx) % width;
  461.     else scrollx %= width;
  462.     if (scrolly < 0) scrolly = height - (-scrolly) % height;
  463.     else scrolly %= height;
  464.  
  465.     width/=8;
  466.     height/=8;
  467.     sx    = (scrollx%8);
  468.     offs_x    = width - (scrollx/8);
  469.     sy    = (scrolly%8);
  470.     offs_y    = height - (scrolly/8);
  471.     if(sx>0)
  472.     {
  473.         sx-=8;
  474.         offs_x--;
  475.     }
  476.     if(sy>0)
  477.     {
  478.         sy-=8;
  479.         offs_y--;
  480.     }
  481.  
  482.     /* draw for visible area */
  483.     offs_x *= 2;
  484.     width  *= 2;
  485.     offs_y *= width;
  486.     height = height * width;
  487.     for ( ;sy <= max_y; offs_y+=width,sy+=8)
  488.     {
  489.         offs_y %= height;
  490.         for( ox=offs_x,xx=sx; xx <= max_x; ox+=2,xx+=8 )
  491.         {
  492.             ox %= width;
  493.             code = vid[offs_y+ox+1] + ( ( vid[offs_y+ox] & 0x3f ) << 8 );
  494.             if(char_state[code]!=CHAR_BLANK)
  495.             {
  496.                 drawgfx( bitmap,Machine->gfx[1],
  497.                         code,color,
  498.                         flipscreen, flipscreen,
  499.                         flipscreen ? max_x -7 -xx : xx,
  500.                         flipscreen ? max_y -7 -sy : sy,
  501.                         &Machine->drv->visible_area,
  502.                         (char_state[code]==CHAR_FULL) ? TRANSPARENCY_NONE : TRANSPARENCY_PEN,
  503.                         char_state[code]);
  504.             }
  505.         }
  506.     }
  507. }
  508.  
  509. static void draw_foreground( struct osd_bitmap *bitmap, int layer )
  510. {
  511.     int offs;
  512.     unsigned char *vid = playfields[layer].base;
  513.     int color = objects[layer].color;
  514.     int max_x = Machine->drv->visible_area.max_x;
  515.     int max_y = Machine->drv->visible_area.max_y;
  516.  
  517.     for ( offs = 0; offs < 36*28*2; offs += 2 )
  518.     {
  519.         int sx,sy,code;
  520.  
  521.         code = vid[offs+1] + ( ( vid[offs+0] & 0x3f ) << 8 );
  522.         if(char_state[code]!=CHAR_BLANK)
  523.         {
  524.             sx = ((offs/2) % 36)*8;
  525.             sy = ((offs/2) / 36)*8;
  526.             if(flipscreen)
  527.             {
  528.                 sx = max_x -7 - sx;
  529.                 sy = max_y -7 - sy;
  530.             }
  531.  
  532.             drawgfx( bitmap,Machine->gfx[1],
  533.                     code,color,
  534.                     flipscreen, flipscreen,
  535.                     sx,sy,
  536.                     &Machine->drv->visible_area,
  537.                     (char_state[code]==CHAR_FULL) ? TRANSPARENCY_NONE : TRANSPARENCY_PEN,
  538.                     char_state[code]);
  539.         }
  540.     }
  541. }
  542. #endif
  543.  
  544. /* tilemap callback */
  545. static unsigned char *info_vram;
  546. static int info_color;
  547.  
  548. static void background_get_info(int tile_index)
  549. {
  550.     int code = info_vram[2*tile_index+1]+((info_vram[2*tile_index]&0x3f)<<8);
  551.     SET_TILE_INFO(1,code,info_color);
  552.     tile_info.mask_data = mask_ptr[code];
  553. }
  554.  
  555. static void foreground_get_info(int tile_index)
  556. {
  557.     int code = info_vram[2*tile_index+1]+((info_vram[2*tile_index]&0x3f)<<8);
  558.     SET_TILE_INFO(1,code,info_color);
  559.     tile_info.mask_data = mask_ptr[code];
  560. }
  561.  
  562. static void update_playfield( int layer )
  563. {
  564.     struct tilemap *tilemap = playfields[layer].tilemap;
  565.  
  566.     /* for background , set scroll position */
  567.     if( layer < 4 )
  568.     {
  569.         int scrollx = -playfields[layer].scroll_x + scrolloffsX[layer];
  570.         int scrolly = -playfields[layer].scroll_y + scrolloffsY[layer];
  571.         if ( flipscreen ) {
  572.             scrollx = -scrollx;
  573.             scrolly = -scrolly;
  574.         }
  575.         /* set scroll */
  576.         tilemap_set_scrollx(tilemap,0,scrollx);
  577.         tilemap_set_scrolly(tilemap,0,scrolly);
  578.     }
  579.     info_vram  = playfields[layer].base;
  580.     info_color = objects[layer].color;
  581.     tilemap_update( tilemap );
  582. }
  583.  
  584. /* tilemap draw handler */
  585. void ns1_draw_tilemap(struct osd_bitmap *bitmap,struct gfx_object *object)
  586. {
  587.     int layer = object->code;
  588. #if NAMCOS1_DIRECT_DRAW
  589.     if(namcos1_tilemap_used)
  590. #endif
  591.     tilemap_draw( bitmap , playfields[layer].tilemap , 0 );
  592. #if NAMCOS1_DIRECT_DRAW
  593.     else
  594.     {
  595.         if( layer < 4 )
  596.             draw_background(bitmap,layer);
  597.         else
  598.             draw_foreground(bitmap,layer);
  599.     }
  600. #endif
  601. }
  602.  
  603.  
  604. int namcos1_vh_start( void )
  605. {
  606.     int i;
  607.     struct gfx_object default_object;
  608.  
  609. #if NAMCOS1_DIRECT_DRAW
  610.     /* tilemap used flag select */
  611.     if(Machine->scrbitmap->depth==16)
  612.          /* tilemap system is not supported 16bit yet */
  613.         namcos1_tilemap_used = 0;
  614.     else
  615.         /* selected by game option switch */
  616.         namcos1_tilemap_used = namcos1_tilemap_need;
  617. #endif
  618.  
  619.     /* set table for sprite color == 0x7f */
  620.     for(i=0;i<=15;i++)
  621.         gfx_drawmode_table[i] = DRAWMODE_SHADOW;
  622.  
  623.     /* set static memory points */
  624.     namcos1_paletteram = memory_region(REGION_USER2);
  625.     namcos1_controlram = memory_region(REGION_USER2) + 0x8000;
  626.  
  627.     /* allocate videoram */
  628.     namcos1_videoram = malloc(0x8000);
  629.     if(!namcos1_videoram)
  630.     {
  631.         return 1;
  632.     }
  633.     memset(namcos1_videoram,0,0x8000);
  634.  
  635.     /* initialize object manager */
  636.     memset(&default_object,0,sizeof(struct gfx_object));
  637.     default_object.transparency = TRANSPARENCY_PEN;
  638.     default_object.transparet_color = 15;
  639.     default_object.gfx = Machine->gfx[2];
  640.     objectlist = gfxobj_create(MAX_PLAYFIELDS+MAX_SPRITES,8,&default_object);
  641.     if(objectlist == 0)
  642.     {
  643.         free(namcos1_videoram);
  644.         return 1;
  645.     }
  646.     objects = objectlist->objects;
  647.  
  648.     /* setup tilemap parameter to objects */
  649.     for(i=0;i<MAX_PLAYFIELDS;i++)
  650.     {
  651.         /* set user draw handler */
  652.         objects[i].special_handler = ns1_draw_tilemap;
  653.         objects[i].gfx = 0;
  654.         objects[i].code = i;
  655.         objects[i].visible = 0;
  656.         objects[i].color = i;
  657.     }
  658.  
  659.     /* initialize playfields */
  660.     for (i = 0; i < MAX_PLAYFIELDS; i++)
  661.     {
  662. #if NAMCOS1_DIRECT_DRAW
  663.         if(namcos1_tilemap_used)
  664.         {
  665. #endif
  666.         if ( i < 4 ) {
  667.             playfields[i].base = &namcos1_videoram[i<<13];
  668.             playfields[i].tilemap =
  669.                 tilemap_create(background_get_info,tilemap_scan_rows,TILEMAP_BITMASK,
  670.                                 8,8,64,i==3 ? 32 : 64);
  671.         } else {
  672.             playfields[i].base = &namcos1_videoram[FG_OFFSET+0x10+( ( i - 4 ) * 0x800 )];
  673.             playfields[i].tilemap =
  674.                 tilemap_create(foreground_get_info,tilemap_scan_rows,TILEMAP_BITMASK,
  675.                                 8,8,36,28);
  676.         }
  677. #if NAMCOS1_DIRECT_DRAW
  678.         }
  679.         else
  680.         {
  681.             if ( i < 4 ) {
  682.                 playfields[i].base = &namcos1_videoram[i<<13];
  683.                 playfields[i].width  = 64*8;
  684.                 playfields[i].height = ( i == 3 ) ? 32*8 : 64*8;
  685.             } else {
  686.                 playfields[i].base = &namcos1_videoram[FG_OFFSET+0x10+( ( i - 4 ) * 0x800 )];
  687.                 playfields[i].width  = 36*8;
  688.                 playfields[i].height = 28*8;
  689.             }
  690.         }
  691. #endif
  692.         playfields[i].scroll_x = 0;
  693.         playfields[i].scroll_y = 0;
  694.     }
  695.     namcos1_set_flipscreen(0);
  696.  
  697.     /* initialize sprites and display controller */
  698.     for(i=0;i<0x7ef;i++)
  699.         namcos1_spriteram_w(i,0);
  700.     for(i=0;i<0xf;i++)
  701.         namcos1_displaycontrol_w(i,0);
  702.     for(i=0;i<0xff;i++)
  703.         namcos1_playfield_control_w(i,0);
  704.  
  705. #if NAMCOS1_DIRECT_DRAW
  706.     if(namcos1_tilemap_used)
  707.     {
  708. #endif
  709.     /* build tilemap mask data from gfx data of mask */
  710.     /* because this driver use ORIENTATION_ROTATE_90 */
  711.     /* mask data can't made by ROM image             */
  712.     {
  713.         const struct GfxElement *mask = Machine->gfx[0];
  714.         int total  = mask->total_elements;
  715.         int width  = mask->width;
  716.         int height = mask->height;
  717.         int line,x,c;
  718.  
  719.         mask_ptr = malloc(total * sizeof(unsigned char *));
  720.         if(mask_ptr == 0)
  721.         {
  722.             free(namcos1_videoram);
  723.             return 1;
  724.         }
  725.         mask_data = malloc(total * 8);
  726.         if(mask_data == 0)
  727.         {
  728.             free(namcos1_videoram);
  729.             free(mask_ptr);
  730.             return 1;
  731.         }
  732.  
  733.         for(c=0;c<total;c++)
  734.         {
  735.             unsigned char *src_mask = &mask_data[c*8];
  736.             for(line=0;line<height;line++)
  737.             {
  738.                 unsigned char  *maskbm = get_gfx_pointer(mask,c,line);
  739.                 src_mask[line] = 0;
  740.                 for (x=0;x<width;x++)
  741.                 {
  742.                     src_mask[line] |= maskbm[x]<<(7-x);
  743.                 }
  744.             }
  745.             mask_ptr[c] = src_mask;
  746.             if(mask->pen_usage)
  747.             {
  748.                 switch(mask->pen_usage[c])
  749.                 {
  750.                 case 0x01: mask_ptr[c] = TILEMAP_BITMASK_TRANSPARENT; break; /* blank */
  751.                 case 0x02: mask_ptr[c] = TILEMAP_BITMASK_OPAQUE; break; /* full */
  752.                 }
  753.             }
  754.         }
  755.     }
  756.  
  757. #if NAMCOS1_DIRECT_DRAW
  758.     }
  759.     else /* namcos1_tilemap_used */
  760.     {
  761.  
  762.     /* build char mask status table */
  763.     {
  764.         const struct GfxElement *mask = Machine->gfx[0];
  765.         const struct GfxElement *pens = Machine->gfx[1];
  766.         int total  = mask->total_elements;
  767.         int width  = mask->width;
  768.         int height = mask->height;
  769.         int line,x,c;
  770.  
  771.         char_state = malloc( total );
  772.         if(char_state == 0)
  773.         {
  774.             free(namcos1_videoram);
  775.             return 1;
  776.         }
  777.  
  778.         for(c=0;c<total;c++)
  779.         {
  780.             unsigned char ordata = 0;
  781.             unsigned char anddata = 0xff;
  782.             for(line=0;line<height;line++)
  783.             {
  784.                 unsigned char  *maskbm = get_gfx_pointer(mask,c,line);
  785.                 for (x=0;x<width;x++)
  786.                 {
  787.                     ordata    |= maskbm[x];
  788.                     anddata &= maskbm[x];
  789.                 }
  790.             }
  791.             if(!ordata)  char_state[c]=CHAR_BLANK;
  792.             else if(anddata) char_state[c]=CHAR_FULL;
  793.             else
  794.             {
  795.                 /* search non used pen */
  796.                 unsigned char penmap[256];
  797.                 unsigned char trans_pen;
  798.                 memset(penmap,0,256);
  799.                 for(line=0;line<height;line++)
  800.                 {
  801.                     unsigned char  *pensbm = get_gfx_pointer(pens,c,line);
  802.                     for (x=0;x<width;x++)
  803.                         penmap[pensbm[x]]=1;
  804.                 }
  805.                 for(trans_pen=2;trans_pen<256;trans_pen++)
  806.                 {
  807.                     if(!penmap[trans_pen]) break;
  808.                 }
  809.                 char_state[c]=trans_pen; /* transparency color */
  810.                 /* fill transparency color */
  811.                 for(line=0;line<height;line++)
  812.                 {
  813.                     unsigned char  *maskbm = get_gfx_pointer(mask,c,line);
  814.                     unsigned char  *pensbm = get_gfx_pointer(pens,c,line);
  815.                     for (x=0;x<width;x++)
  816.                     {
  817.                         if(!maskbm[x]) pensbm[x] = trans_pen;
  818.                     }
  819.                 }
  820.             }
  821.         }
  822.     }
  823.  
  824.     } /* namcos1_tilemap_used */
  825. #endif
  826.  
  827.     for (i = 0;i < TILECOLORS;i++)
  828.     {
  829.         palette_shadow_table[Machine->pens[i+SPRITECOLORS]] = Machine->pens[i+SPRITECOLORS+TILECOLORS];
  830.     }
  831.  
  832.     return 0;
  833. }
  834.  
  835. void namcos1_vh_stop( void )
  836. {
  837.     free(namcos1_videoram);
  838.  
  839. #if NAMCOS1_DIRECT_DRAW
  840.     if(namcos1_tilemap_used)
  841.     {
  842. #endif
  843.     free(mask_ptr);
  844.     free(mask_data);
  845. #if NAMCOS1_DIRECT_DRAW
  846.     }
  847.     else
  848.         free(char_state);
  849. #endif
  850. }
  851.  
  852. void namcos1_set_optimize( int optimize )
  853. {
  854. #if NAMCOS1_DIRECT_DRAW
  855.     namcos1_tilemap_need = optimize;
  856. #endif
  857. }
  858.  
  859. void namcos1_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  860. {
  861.     int i;
  862.     struct gfx_object *object;
  863.     unsigned short palette_map[MAX_SPRITES+1];
  864.     const unsigned char *remapped;
  865.  
  866.     /* update all tilemaps */
  867. #if NAMCOS1_DIRECT_DRAW
  868.     if(namcos1_tilemap_used)
  869.     {
  870. #endif
  871.     for(i=0;i<MAX_PLAYFIELDS;i++)
  872.         update_playfield(i);
  873. #if NAMCOS1_DIRECT_DRAW
  874.     }
  875. #endif
  876.     /* object list (sprite) update */
  877.     gfxobj_update();
  878.     /* palette resource marking */
  879.     palette_init_used_colors();
  880.     memset(palette_map, 0, sizeof(palette_map));
  881.     for(object=objectlist->first_object ; object!=0 ; object=object->next)
  882.     {
  883.         if (object->visible)
  884.         {
  885.             int color = object->color;
  886.             if(object->gfx)
  887.             {    /* sprite object */
  888.                 if (sprite_palette_state[color])
  889.                 {
  890.                     if (color != 0x7f) namcos1_palette_refresh(16*color, 16*color, 15);
  891.                     sprite_palette_state[color] = 0;
  892.                 }
  893.  
  894.                 palette_map[color] |= Machine->gfx[2]->pen_usage[object->code];
  895.             }
  896.             else
  897.             {    /* playfield object */
  898.                 if (tilemap_palette_state[color])
  899.                 {
  900.                     namcos1_palette_refresh(128*16+256*color, 128*16+256*playfields[color].color, 256);
  901. #if NAMCOS1_DIRECT_DRAW
  902.                     if(!namcos1_tilemap_used)
  903.                     {
  904.                         /* mark used flag */
  905.                         memset(&palette_used_colors[color*256+128*16],PALETTE_COLOR_VISIBLE,256);
  906.                     }
  907. #endif
  908.                     tilemap_palette_state[color] = 0;
  909.                 }
  910.             }
  911.         }
  912.     }
  913.  
  914.     for (i = 0; i < MAX_SPRITES; i++)
  915.     {
  916.         int usage = palette_map[i], j;
  917.         if (usage)
  918.         {
  919.             for (j = 0; j < 15; j++)
  920.                 if (usage & (1 << j))
  921.                     palette_used_colors[i * 16 + j] |= PALETTE_COLOR_VISIBLE;
  922.         }
  923.     }
  924.     /* background color */
  925.     palette_used_colors[BACKGROUNDCOLOR] |= PALETTE_COLOR_VISIBLE;
  926.  
  927.     if ( ( remapped = palette_recalc() ) )
  928.     {
  929. #if NAMCOS1_DIRECT_DRAW
  930.         if(namcos1_tilemap_used)
  931. #endif
  932.         for (i = 0;i < MAX_PLAYFIELDS;i++)
  933.         {
  934.             int j;
  935.             const unsigned char *remapped_layer = &remapped[128*16+256*i];
  936.             for (j = 0;j < 256;j++)
  937.             {
  938.                 if (remapped_layer[j])
  939.                 {
  940.                     tilemap_mark_all_pixels_dirty(playfields[i].tilemap);
  941.                     break;
  942.                 }
  943.             }
  944.         }
  945.     }
  946.  
  947. #if NAMCOS1_DIRECT_DRAW
  948.     if(namcos1_tilemap_used)
  949. #endif
  950.     tilemap_render(ALL_TILEMAPS);
  951.     /* background color */
  952.     fillbitmap(bitmap,Machine->pens[BACKGROUNDCOLOR],&Machine->drv->visible_area);
  953.     /* draw objects (tilemaps and sprites) */
  954.     gfxobj_draw(objectlist);
  955. }
  956.